#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <string.h>

CvHaarClassifierCascade* load_object_detector( const char* cascade_path )
{
    return (CvHaarClassifierCascade*)cvLoad( cascade_path );
}

void detect_and_draw_objects( IplImage* image,
                              CvHaarClassifierCascade* cascade,
                              int do_pyramids )
{
    IplImage* small_image = image;
    CvMemStorage* storage = cvCreateMemStorage(0);
    CvSeq* faces;
    int i, scale = 1;

    /* if the flag is specified, down-scale the input image to get a
       performance boost w/o loosing quality (perhaps) */
    /* use the fastest variant */

    faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 0, 0);

    /* draw all the rectangles */
    for( i = 0; i < faces->total; i++ )
    {
        /* extract the rectangles only */
        CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i );
        cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale),
                     cvPoint((face_rect.x+face_rect.width)*scale,
                             (face_rect.y+face_rect.height)*scale),
                     CV_RGB(255,0,0), 1 );
    }

    if( small_image != image )
        cvReleaseImage( &small_image );
    cvReleaseMemStorage( &storage );
}

/* takes image filename and cascade path from the command line */
int main( int argc, char** argv )
{
    IplImage* image;
    if(argc != 3) {
        printf("usage: face_detection_cpu [image] [template]\n");
        return 0;
    }
        
    image = cvLoadImage( argv[1], 1 );
    if(image == NULL) {
        printf("error: image == NULL\n");
        return 0;
    }
    
    CvHaarClassifierCascade* cascade = load_object_detector(argv[2]);
    if(cascade == NULL) {
        printf("error: cascade == NULL\n");
        return 0;
    }

    detect_and_draw_objects( image, cascade, 1 );
    cvSaveImage("result_cpu.png", image);
    cvReleaseHaarClassifierCascade( &cascade );
    cvReleaseImage( &image );
    return 0;
}

